package com.acme.chat.newclient;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import com.acme.chat.message.MessageType;

public class TcpProxyAgent implements Runnable, SendMessageListener {

    private Client client;

    private Socket socket;
    private ObjectInputStream inStream;
    private ObjectOutputStream outStream;

    private volatile boolean keepGoing;

    public TcpProxyAgent(Client client) {
        this.client = client;
    }

    @Override
    public void run() {
        while (keepGoing) {
            try {
                ServerMessage message = (ServerMessage) inStream.readObject();
                process(message);
            } catch (IOException e) {
                break;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

        stop();
    }

    private void process(ServerMessage message) {
        client.incommingMessage(message);
    }

    @Override
    public void onSendMessage(ClientMessage message) {
        MessageType type = message.getType();

        switch (type) {
        case CONNECT:
            start(message);
            break;
        case DISCONNECT:
            writeMessage(message);
            keepGoing = false;
            break;
        default:
            writeMessage(message);
            break;
        }
    }

    private void writeMessage(ClientMessage message) {
        try {
            outStream.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean start(ClientMessage message) {

        try {
            socket = new Socket(message.getServerName(), message.getPort());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        try {
            inStream = new ObjectInputStream(socket.getInputStream());
            outStream = new ObjectOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        try {
            outStream.writeObject(client.getName());
            outStream.writeObject(client.getRoom());
            outStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        keepGoing = true;
        Thread t = new Thread(this);
        t.start();
        t.setName(this.toString());
        return true;
    }

    private void stop() {
        keepGoing = false;
        client.removeSendMessageListener(this);
        try {
            if (inStream != null) {
                inStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if (socket != null) {
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return "TcpProxyAgent: socket: " + socket + " " + client;
    }
}
